﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
// 原题连接：https://leetcode.cn/problems/sort-characters-by-frequency/
/*
题目描述：
给定一个字符串 s ，根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。

返回 已排序的字符串 。如果有多个答案，返回其中任何一个。

 

示例 1:

输入: s = "tree"
输出: "eert"
解释: 'e'出现两次，'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外，"eetr"也是一个有效的答案。
示例 2:

输入: s = "cccaaa"
输出: "cccaaa"
解释: 'c'和'a'都出现三次。此外，"aaaccc"也是有效的答案。
注意"cacaca"是不正确的，因为相同的字母必须放在一起。
示例 3:

输入: s = "Aabb"
输出: "bbAa"
解释: 此外，"bbaA"也是一个有效的答案，但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。
 

提示:

1 <= s.length <= 5 * 105
s 由大小写英文字母和数字组成
*/

// 开始解题：
// 方法1——按照出现的频率排序
#define HASH_FIND_CHAR(head, findint, out) HASH_FIND(hh, head, findint, sizeof(char), out)
#define HASH_ADD_CHAR(head, intfield, add) HASH_ADD(hh, head, intfield, sizeof(char), add)

struct HashTable {
    char key;
    int val;
    UT_hash_handle hh;
};

int cmp(struct HashTable* a, struct HashTable* b) {
    return b->val - a->val;
}

char* frequencySort(char* s) {
    struct HashTable* hashTable = NULL;
    int length = strlen(s);
    for (int i = 0; i < length; i++) {
        struct HashTable* tmp;
        HASH_FIND_CHAR(hashTable, &s[i], tmp);
        if (tmp == NULL) {
            tmp = malloc(sizeof(struct HashTable));
            tmp->key = s[i], tmp->val = 1;
            HASH_ADD_CHAR(hashTable, key, tmp);
        }
        else {
            tmp->val++;
        }
    }
    int n = HASH_COUNT(hashTable);
    HASH_SORT(hashTable, cmp);
    int retSize = 0;
    struct HashTable* tmp, * iter;
    HASH_ITER(hh, hashTable, iter, tmp) {
        retSize += iter->val;
    }
    char* ret = malloc(sizeof(char) * (retSize + 1));
    retSize = 0;
    HASH_ITER(hh, hashTable, iter, tmp) {
        for (int i = 0; i < iter->val; i++) {
            ret[retSize++] = iter->key;
        }
    }
    ret[retSize] = '\0';
    return ret;
}

